<?php
class Application_Model_CompanyMapper
{   // Database fields mapping
    const ID        = 'com_id';
    const NAME      = 'com_name';
    const DESC      = 'com_desc';
    const TELEFON   = 'com_telefon';
    const ADRESA    = 'com_adresa';
    const SITE      = 'com_site';
    const LEVEL     = 'com_level';
    const CREATED   = 'com_ac_create';
    const UPDATED   = 'com_ac_update';
    const URL       = 'com_url';

    /**
     * @var Zend_Db_Adaptor
     */
    protected $_db;
    

    public function  __construct()
    {
        $this->_db = Zend_Registry::get('db_adaptor');
    }

    /********************************************************************/

    /**
     * This function saves passed company or array of companies (recursively)
     * to the database storage.
     *
     * @param Application_Model_Company $company
     * @return bool|string
     * @todo Збереження компанії в БД - insert-update
     *
     */
    public function save($company)
    {   $res = false;
        if ($company instanceof Application_Model_Company) {
            // Under Construction
            $c = $company;

            $data[self::NAME]      = $c->getName();
            $data[self::DESC]      = $c->getDesc();
            $data[self::TELEFON]   = $c->getTelefon();
            $data[self::ADRESA]    = $c->getAdresa();
            $data[self::SITE]      = $c->getSite();
            $data[self::LEVEL]     = $c->getLevel();
            $data[self::CREATED]   = $c->getCreated();
            $data[self::UPDATED]   = $c->getUpdated();
            $data[self::URL]       = $c->getUrl();

            $catId = $company->getCategory()->getId();
            $comCat = array (Application_Model_CategoryMapper::ID => $catId);

var_dump($company->getId());

            $this->_db->beginTransaction();
            try {
                $this->_db->insert('company', $data);

                $foo = $comCat[self::ID] = $this->_db->lastInsertId();
                $this->_db->insert('com_cat', $comCat);
                $this->_db->commit();

                $res = true;
            } catch (Exception $e) {
                $this->_db->rollBack();
                $res = $e->getMessage();
            }
            
            
        } else throw new Exception ('Invalid company: must be A*M*C or array');

        return $res;
    }

    /*************************************************************************/

    /**
     * Повертає масив компаній, вибраний з бази
     *
     * Якщо вказана категорія $filter['category'] (id або url) - то вибирає
     * компанії лише із вказаної категорії
     *
     * @todo Додатково може фільтрувати по тегу (відкидати зі знайдених результатів
     * ті, які не мають цього тега)
     *
     * @param array|null $filter
     * @return array
     *
     */
    public function fetchMany($filter = null)
    {
        $q = "SELECT * FROM company, com_cat, category "
           . "WHERE company.com_id = com_cat.com_id AND "
           . "com_cat.cat_id = category.cat_id ";

        // If passed $filter we append query with additional
        // conditions (category and limits)
        if (is_array($filter)) {
            
            if (isset( $filter['category'] )) {

                $category = $this->_db->quote( $filter['category'] );
                $q .= " AND ( "
                   . "category.cat_id = $category OR category.cat_url = $category"
                   . ") ";
            } // category filtration
            
            
            $q .= " ORDER BY `company`.`com_id` ";


            if (isset( $filter['limit'] ) && is_array($filter['limit'])) {
                $l = $filter['limit'];

                if ( isset($l[0]) ) {
                    $limit1 = (int) $l[0];
                    $q .= " LIMIT $limit1";

                    // And if passed, we'll append limit 2
                    if ( isset($l[1]) ) {
                        $limit2 = (int) $l[1];
                        $q .= ", $limit2";
                    } // limit 2

                } // limit1

            } // limits appending
        } else {
            $q .= " ORDER BY `company`.`com_id` DESC ";
        }

        // Запит остаточно сформований
        
        // Fetching all companies
        $this->_db->setFetchMode(Zend_Db::FETCH_ASSOC);
        $resCompanies = $this->_db->fetchAll($q);

        foreach ($resCompanies as $key => $resCompany) {
            $comId = $resCompany[self::ID];

            // вибірка тегів і фільтрація за тегом
            $q = "SELECT * FROM com_tag, tag WHERE "
               . " com_tag.com_id = $comId "
               . " AND com_tag.tag_id = tag.tag_id";

            //@todo BUG ??? fetchAssoc($q) returns only first row
            $this->_db->setFetchMode(Zend_Db::FETCH_ASSOC);
            $tags = $this->_db->fetchAll($q);

            foreach ($tags as $tagKey => $tag) {

                if (isset ($filter['tag'])) {
                    //@todo Tag filtretion якщо не містить цього тега,
                    // то відкинути результат - unset + continue 2
                }

                //@todo Q: Створюємо новий обєкт для тега, скільки б раз він не повторявся раніше (???)
                $tagObj = new Application_Model_Tag();

                $tagObj->setId     ( $tag['tag_id']  );
                $tagObj->setText   ( $tag['text']    );
                $tagObj->setUrl    ( $tag['tag_url'] );
                $tagObj->setStatus ( $tag['status']  );

                $tags[$tagKey] = $tagObj;
            } //перебір тегів

            
            $company = new Application_Model_Company();
            
            $company->setId      ( $resCompany[self::ID]      );
            $company->setName    ( $resCompany[self::NAME]    );
            $company->setDesc    ( $resCompany[self::DESC]    );
            $company->setTelefon ( $resCompany[self::TELEFON] );
            $company->setAdresa  ( $resCompany[self::ADRESA]  );
            $company->setSite    ( $resCompany[self::SITE]    );
            $company->setLevel   ( $resCompany[self::LEVEL]   );
            $company->setCreated ( $resCompany[self::CREATED] );
            $company->setUpdated ( $resCompany[self::UPDATED] );
            $company->setUrl     ( $resCompany[self::URL]     );
            
            $company->setTags($tags);

            $categoryObj = new Application_Model_Category();
            $categoryObj->setId($resCompany['cat_id']);
            $categoryObj->setText($resCompany['cat_text']);
            $categoryObj->setUrl($resCompany['cat_url']);

            $company->setCategory($categoryObj);

            $resCompanies[$key] = $company;

        }//перебір вибраних компаній

        return $resCompanies;

    }//fetchMany()

    /**
     *
     * @param int|string $param Айді чи Урл
     * @return array Масив з записами бази даних 
     *
     *
     * 
     */
    public function find($param)
    {
        $idField = self::ID;
        $urlField = self::URL;
        $q = "SELECT * FROM company WHERE `$idField` = '$param' "
           . " OR `$urlField` = '$param'";

        $res = $this->_db->fetchRow($q);
        return $res;

    }

    public function exists($param, &$name = null)
    {
        $res = $this->find($param);
        
        if (isset($res[self::ID])) {
            $name = $res[self::NAME];
            return $res[self::ID];
        } else return false;
    }

    public function dbEntryToCompanyObj($dbEntry)
    {   
        if (is_array($dbEntry)) { 
            $options = array (
                'id'      => $dbEntry [self::ID],
                'name'    => $dbEntry [self::NAME],
                'desc'    => $dbEntry [self::DESC],
                'telefon' => $dbEntry [self::TELEFON],
                'adresa'  => $dbEntry [self::ADRESA],
                'site'    => $dbEntry [self::SITE],
                'level'   => $dbEntry [self::LEVEL],
                'updated' => $dbEntry [self::UPDATED],
                'created' => $dbEntry [self::CREATED],
                'url'     => $dbEntry [self::URL]
            );

            return new Application_Model_Company($options);

        } else return false;
    }
    
    /*************************************************************************/
    
    public function delete($param)
    {
        $id = self::ID;
        $url = self::URL;
        
        $where = "`$id` = '$param' OR `$url` = '$param'";
        
        return $this->_db->delete('company', $where);
    }



}

